
splitAll :: Eq a => [a] -> [a] -> [[a]]
splitAll _ [] = []
splitAll delims xs = 
    token : splitAll delims rest
    where
        isDelimiter = (`elem` delims)
        token       = takeWhile (not . isDelimiter) xs
        rest        = dropWhile isDelimiter $ dropWhile (not . isDelimiter) xs

type Card = Int
type Deck = [Card]

type GameState = (Deck, Deck)

parseInput :: String -> GameState
parseInput str = (deck1, deck2)
    where
        tokens = splitAll [""] $ lines str

        deck1 = map read . tail $ tokens !! 0
        deck2 = map read . tail $ tokens !! 1

rounding :: GameState -> GameState
rounding state@(deck1, deck2)
    | head1 > head2 = (rest1 ++ [head1,head2], rest2)
    | head1 < head2 = (rest1, rest2 ++ [head2,head1])
    where
        head1 = head deck1
        head2 = head deck2

        rest1 = tail deck1
        rest2 = tail deck2

play :: GameState -> GameState
play state@(deck1, deck2) = 
    if null deck1 || null deck2 
        then state
        else play $ rounding state

score :: GameState -> Card
score (deck1, deck2) = 
    if null deck1 
        then calScore deck2
        else calScore deck1
    where
        calScore = sum . zipWith (*) [1..] . reverse

main :: IO ()
main = do
    input <- readFile "input.txt"
    print . score . play . parseInput $ input

    